package com.av.android;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.MultiAutoCompleteTextView;
import android.widget.Spinner;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ReportActivity extends BaseActivity {
	private static List<Tag> TAGS;
	private static final String[] STATUS = new String[] { "Detected",
		"InProgress", "FriendlyLocation" };
	private List<ObstacleType> obstacles;
	private ArrayList<String> obstacleNames;
	private ProgressDialog progress;
	private Spinner spinnerObstacle;
	private Spinner spinnerStatus;
	private EditText descEditText;
	private EditText reportNameEditText;
	private Button addReportButton;
	private static final int SELECT_PICTURE = 1;
	private static final int TAKE_PHOTO_CODE = 2;
	private static final int SELECT_VIDEO = 3;
	private static final int TAKE_VIDEO_CODE = 4;
	private static final int SELECT_AUDIO = 5;
	private static final int TAKE_AUDIO_CODE = 6;

	private ImageView photoThumbnail;
	private ImageView videoThumbnail;
	private ImageView audioThumbnail;

	private Bitmap photo;
	private Bitmap videoBitmap;

	private Uri audioUri;
	private Uri videoUri;
	private Uri imageUri;
	MultiAutoCompleteTextView textView;

	@Override
	public void onCreate(Bundle b) {
		super.onCreate(b);
		setContentView(R.layout.activity_report);
		
		
		textView = (MultiAutoCompleteTextView) findViewById(R.id.edit_tag);
		textView.setThreshold(1);

		textView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
		
		new Thread(new Runnable() {
			
			public void run() {
				getTags();
				
			}
		}).start();
		descEditText = (EditText) findViewById(R.id.description);
		reportNameEditText = (EditText)findViewById(R.id.report_name);
		addReportButton = (Button)findViewById(R.id.add_report);
		addReportButton.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {

				new Thread(new Runnable() {

					public void run() {
						runOnUiThread(new Runnable() {
							public void run() {
								
								progress = ProgressDialog.show(ReportActivity.this, "", "Uploading...");
							}
						});
						postReport();
					}
				}).start();

			}
		});
		photoThumbnail = (ImageView) findViewById(R.id.photo);
		videoThumbnail = (ImageView) findViewById(R.id.video);
		audioThumbnail = (ImageView) findViewById(R.id.audio);

		spinnerObstacle = (Spinner) findViewById(R.id.obstacle_types);
		obstacles = new ArrayList<ObstacleType>();
		spinnerObstacle.setAdapter(new ArrayAdapter<ObstacleType>(
				getApplicationContext(),
				android.R.layout.simple_spinner_dropdown_item, obstacles));
		spinnerStatus = (Spinner) findViewById(R.id.status);
		spinnerStatus.setAdapter(new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_dropdown_item, STATUS));
		spinnerStatus.setSelection(0);
		new GetObstaclesTask().execute();

		Button addPhoto = (Button) findViewById(R.id.add_photo);
		addPhoto.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {

				// in onCreate or any event where your want the user to
				// select a file
				Intent intent = new Intent();
				intent.setType("image/*");
				intent.setAction(Intent.ACTION_GET_CONTENT);
				startActivityForResult(
						Intent.createChooser(intent, "Select Picture"),
						SELECT_PICTURE);
			}
		});
		Button takePhoto = (Button) findViewById(R.id.take_photo);
		takePhoto.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {
				takePhoto();

			}
		});
		Button addVideo = (Button) findViewById(R.id.add_video);
		addVideo.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {

				// in onCreate or any event where your want the user to
				// select a file
				Intent intent = new Intent();
				intent.setType("video/*");
				intent.setAction(Intent.ACTION_GET_CONTENT);
				startActivityForResult(
						Intent.createChooser(intent, "Select Video"),
						SELECT_VIDEO);
			}
		});
		Button takeVideo = (Button) findViewById(R.id.record_video);
		takeVideo.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {
				takeVideo();

			}
		});
		Button addAudio = (Button) findViewById(R.id.add_audio);
		addAudio.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {

				// in onCreate or any event where your want the user to
				// select a file
				Intent intent = new Intent();
				intent.setType("audio/*");
				intent.setAction(Intent.ACTION_GET_CONTENT);

				startActivityForResult(
						Intent.createChooser(intent, "Select Audio"),
						SELECT_AUDIO);
			}
		});
		Button takeAudio = (Button) findViewById(R.id.record_sound);
		takeAudio.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {
				takeAudio();

			}
		});

	}

	protected void getTags() {
		// TODO Auto-generated method stub
		TAGS = Utils.getTags();
		runOnUiThread(new Runnable() {
			
			public void run() {
				// TODO Auto-generated method stub
				ArrayAdapter<Tag> adapter = new ArrayAdapter<Tag>(ReportActivity.this,
						android.R.layout.simple_dropdown_item_1line, TAGS);
				textView.setAdapter(adapter);
			}
		});
	}

	public class GetObstaclesTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			
				obstacles =Utils.GetObstacles();
				return null;
		}

		@Override
		public void onPostExecute(Void v) {
			spinnerObstacle.setAdapter(new ArrayAdapter<ObstacleType>(
					getApplicationContext(),
					android.R.layout.simple_spinner_dropdown_item, obstacles));

		}

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if ( resultCode != RESULT_CANCELED && resultCode == RESULT_OK) {
			switch (requestCode) {
			case TAKE_PHOTO_CODE:
				imageUri = data.getData();
				// TODO Auto-generated method stub
				photoThumbnail.setBackgroundDrawable(null);
				photoThumbnail.setImageBitmap((Bitmap)(data.getExtras().get("data")));
				break;
			case SELECT_PICTURE:

				imageUri = data.getData();

				photo = setImageToImageView(getRealPathFromURI(imageUri));
				System.out.println(photo.getRowBytes()*photo.getHeight()+" bytes");
				photoThumbnail.setImageBitmap(photo);
				photoThumbnail.setBackgroundDrawable(null);

				break;
			case TAKE_VIDEO_CODE:
				videoUri = data.getData();
				videoBitmap = ThumbnailUtils.createVideoThumbnail(getRealPathFromURI(videoUri),  MediaStore.Video.Thumbnails.MICRO_KIND);
				videoThumbnail.setImageBitmap(videoBitmap);
				videoThumbnail.setBackgroundDrawable(null);
				break;
			case SELECT_VIDEO:
				videoUri = data.getData();
				videoBitmap = ThumbnailUtils.createVideoThumbnail(getRealPathFromURI(videoUri),  MediaStore.Video.Thumbnails.MICRO_KIND);
				videoThumbnail.setImageBitmap(videoBitmap);
				videoThumbnail.setBackgroundDrawable(null);
				break;
			case TAKE_AUDIO_CODE:
				audioUri = data.getData();
				audioThumbnail.setBackgroundResource(R.drawable.audio_recorded);
				break;
			case SELECT_AUDIO:
				audioUri = data.getData();
				audioThumbnail.setBackgroundResource(R.drawable.audio_recorded);
				break;
			default:

				break;
			}
		}
	}

	// UPDATED!
	public String getPath(Uri uri) {
		String[] projection = { MediaStore.Images.Media.DATA };
		Cursor cursor = managedQuery(uri, projection, null, null, null);
		if (cursor != null) {
			// HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
			// THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			return cursor.getString(column_index);
		} else
			return null;
	}

	private void takePhoto() {
		final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		Camera mCamera = Camera.open();
		Method rotateMethod;
		try {
			rotateMethod = android.hardware.Camera.class.getMethod("setDisplayOrientation", int.class);
			rotateMethod.invoke(mCamera, 90);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println(e);
		} 
		mCamera.release();
		mCamera = null;
		startActivityForResult(intent, TAKE_PHOTO_CODE);
	}

	private void takeVideo() {
		Camera mCamera = Camera.open();
		Method rotateMethod;
		try {
			rotateMethod = android.hardware.Camera.class.getMethod("setDisplayOrientation", int.class);
			rotateMethod.invoke(mCamera, 90);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println(e);
		} 
		mCamera.release();
		mCamera = null;
		final Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
		startActivityForResult(intent, TAKE_VIDEO_CODE);

	}
	private void takeAudio() {
		final Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
		startActivityForResult(intent, TAKE_AUDIO_CODE);

	}
	public String getRealPathFromURI(Uri contentUri) {
		String[] proj = { MediaStore.Images.Media.DATA };
		Cursor cursor = managedQuery(contentUri, proj, null, null, null);
		int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		cursor.moveToFirst();
		return cursor.getString(column_index);
	}
	private void postReport(){

		File audioFile = null;
		if(audioUri!=null)
			audioFile= new File(getRealPathFromURI(audioUri));

		File videoFile = null;
		if(videoUri!=null)
			videoFile= new File(getRealPathFromURI(videoUri));
		File imageFile = null;
		if(imageUri!=null)
			imageFile= new File(getRealPathFromURI(imageUri));
		try {
			HttpClient client = new DefaultHttpClient();  
			String postURL = "http://titan.cmpe.boun.edu.tr:8085/cmpe451Web/addReport";
			HttpPost post = new HttpPost(postURL);

			MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);  

			
			if(audioFile!=null)
				reqEntity.addPart("audio", new FileBody(audioFile,"audio"));
			if(videoFile!=null)
				reqEntity.addPart("video", new FileBody(videoFile,"video"));
			if(imageFile!=null){
				reqEntity.addPart("image", new FileBody(imageFile,"image"));
			}
			reqEntity.addPart("button", new StringBody("Add Report"));
			reqEntity.addPart("locationFieldLat", new StringBody(""+MapsActivity.p.getLatitudeE6()/1E6));
			reqEntity.addPart("locationFieldLong", new StringBody(""+MapsActivity.p.getLongitudeE6()/1E6));
			reqEntity.addPart("reportDescription", new StringBody(descEditText.getText().toString()));
			reqEntity.addPart("status", new StringBody((String) spinnerStatus.getSelectedItem()));
			reqEntity.addPart("obstacleType", new StringBody(((ObstacleType)spinnerObstacle.getSelectedItem()).getObstacleID()+""));
			reqEntity.addPart("reportName", new StringBody(reportNameEditText.getText().toString()));
			reqEntity.addPart("tags", new StringBody(""));
			reqEntity.addPart("userIDandroid", new StringBody(LoginActivity.user.getUser_id()+""));

			post.setEntity(reqEntity); 
			post.setHeader("User-Agent", "android");
			HttpResponse response = client.execute(post);  
			
			HttpEntity resEntity = response.getEntity();  
			if (resEntity != null) {    
				System.out.println(EntityUtils.toString(resEntity));
			}
		} catch (Exception e) {
			e.printStackTrace();
			runOnUiThread(new Runnable() {
				
				public void run() {
					progress.dismiss();
					alertWithOnClickHandler("Report failed. Try again!", "Warning", new Handler());
					
				}
			});
			
		}
		runOnUiThread(new Runnable() {
			
			public void run() {
				progress.dismiss();
				alertAndFinish("Report added. Thanks for your contribution.", "Info");
			}
		});
	}
	public Bitmap setImageToImageView(String filePath) 
	{ 
		// Decode image size 
		BitmapFactory.Options o = new BitmapFactory.Options(); 
		o.inJustDecodeBounds = true; 
		BitmapFactory.decodeFile(filePath, o); 

		// The new size we want to scale to 
		final int REQUIRED_SIZE = 1024; 

		// Find the correct scale value. It should be the power of 2. 
		int width_tmp = o.outWidth, height_tmp = o.outHeight; 
		int scale = 1; 
		while (true) 
		{ 
			if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE) 
				break; 
			width_tmp /= 2; 
			height_tmp /= 2; 
			scale *= 2; 
		} 

		// Decode with inSampleSize 
		BitmapFactory.Options o2 = new BitmapFactory.Options(); 
		o2.inSampleSize = scale; 
		Bitmap bitmap = BitmapFactory.decodeFile(filePath, o2); 
		return bitmap;

	}



}
